/**
 ****************************************
 * @file norflash_drv.h
 * @author: AnRui
 * @version 0.1
 * @date  : 2025-04-24
 * @copyright Copyright (c) 2025
 * @desc:
 *      norflash的型号为: GD25Q128E 使用spi协议
 *      整个norflash 有4k个扇区 每个扇区有4k个字节 一共16M个字节
 *                   有64k个页 每一页有256个字节
 *      手册上提供功能码 在读写擦除之前 先发送功能码
 *      读取数据: 需要首地址 保存数据的数组 和需要读取数据的个数
 *      写入数据: 写入之前需要擦除数据。因为 NOR Flash的物理特性限制 写入操作只能将比特从 1 改为 0，若需将 0 改为 1，必须通过擦除操作实现
 *               擦除是以扇区为单位的 写入是以页为单位的
 * ***************************************
 */
#ifndef __NORFLASH_H__
#define __NORFLASH_H__
#include "gd32f30x.h"
#include "spi_soft_drv.h"
#include "spi_hard_drv.h"
#include "delay.h"
#include <stdio.h>

 // CS
#define NOR_FLASH_CS_RCU	       RCU_GPIOE
#define NOR_FLASH_CS_PORT	       GPIOE
#define NOR_FLASH_CS_PIN	       GPIO_PIN_2
#define NOR_FLASH_CS(bit)          gpio_bit_write(NOR_FLASH_CS_PORT, NOR_FLASH_CS_PIN, bit?SET:RESET)
#define NOR_FLASH_CS_SELECT()      NOR_FLASH_CS(0)
#define NOR_FLASH_CS_DESELECT()    NOR_FLASH_CS(1)

// SPI相关函数
//#define SPI_INIT_FUNCTION()      SpiSoftInit()
//#define SPI_RW_FUNCTION(data)    SpiSoftReadWriteByte(data)
#define SPI_INIT_FUNCTION()      SpiHardDrvInit()
#define SPI_RW_FUNCTION(data)    SpiHardDrvReadWriteByte(data)

//存储能力
// 整个norflash 一共有 256个块 1块有16扇区 1个扇区有16页  1页有256个字节
#define NORFLASH_SECTOR_SIZE 						  4096 //扇区大小，字节
#define NORFLASH_SECTOR_COUNT 						4096 //扇区个数
#define NORFLASH_PAGE_SIZE    						256  //一页的大小，字节
#define NORFLASH_BLOCK_SIZE  						(16 * NORFLASH_SECTOR_SIZE)
#define NORFLASH_SIZE        						(256 * NORFLASH_BLOCK_SIZE)
#define NORFLASH_MAX_ADDR        					0xFFFFFF
// 只读时写入的数据 norflash内部默认都是1
#define DUMMY_BYTE							        0xFF
//功能码
#define NORFLASH_WRITE_ENABLE						0x06
#define NORFLASH_WRITE_DISABLE						0x04
#define NORFLASH_READ_STATUS_REGISTER_1				0x05
#define NORFLASH_READ_STATUS_REGISTER_2				0x35
#define NORFLASH_WRITE_STATUS_REGISTER				0x01
#define NORFLASH_PAGE_PROGRAM						0x02
#define NORFLASH_QUAD_PAGE_PROGRAM					0x32
#define NORFLASH_BLOCK_ERASE_64KB					0xD8
#define NORFLASH_BLOCK_ERASE_32KB					0x52
#define NORFLASH_SECTOR_ERASE_4KB					0x20
#define NORFLASH_CHIP_ERASE							0xC7
#define NORFLASH_ERASE_SUSPEND						0x75
#define NORFLASH_ERASE_RESUME						0x7A
#define NORFLASH_POWER_DOWN							0xB9
#define NORFLASH_HIGH_PERFORMANCE_MODE				0xA3
#define NORFLASH_CONTINUOUS_READ_MODE_RESET			0xFF
#define NORFLASH_RELEASE_POWER_DOWN_HPM_DEVICE_ID	0xAB
#define NORFLASH_MANUFACTURER_DEVICE_ID				0x90
#define NORFLASH_READ_UNIQUE_ID						0x4B
#define NORFLASH_JEDEC_ID							0x9F
#define NORFLASH_READ_DATA							0x03
#define NORFLASH_FAST_READ							0x0B
#define NORFLASH_FAST_READ_DUAL_OUTPUT				0x3B
#define NORFLASH_FAST_READ_DUAL_IO					0xBB
#define NORFLASH_FAST_READ_QUAD_OUTPUT				0x6B
#define NORFLASH_FAST_READ_QUAD_IO					0xEB
#define NORFLASH_OCTAL_WORD_READ_QUAD_IO			0xE3

#define NORFLASH_MID_DID      (0xC84018UL)
// 超时次数 循环一次的时间为 执行一次时间间隔的函数
// 写一页数据的标准时间为0.6ms   擦除一个扇区数据的标准时间为 45ms 擦除一个块区数据的标准时间为 150|250ms 擦除整个芯片数据的标准时间为 7s
#define OUT_TIME_TIMES  1000
#define TIME_SPACE_FUNCTION()  DelayNus(100)



/**
 * @desc  : norflash初始化
 * @date  : 2025-04-24
 * @author: AnRui
 * @note  :
 */
void NorFlashDrvInit(void);

/**
 * @desc  : 读取Norflash的 ID
 * @date  : 2025-04-24
 * @author: AnRui
 * @param : mid - {参数说明}: 存储制造商ID
 * @param : did - {参数说明}: 存储设备ID
 * @note  :  MID: 0xC8, DID: 0x4018
 */
void ReadNorflashID(uint8_t* mid, uint16_t* did);


/**
 * @desc  : 指定地址开始读出指定个数的数据
 * @date  : 2025-04-24
 * @author: AnRui
 * @param : readAddr - {参数说明}:  readAddr,读取地址
 * @param : pBuffer - {参数说明}:  pBuffer,数组首地址
 * @param : len - {参数说明}: len,要读出的数据个数
 * @note  : 读数据过程
 *          1.先发送读的功能码：
 *          2.发送24位地址  高位 中位 低位
 *          3.读取数据
 */
void ReadNorflashData(uint32_t readAddr, uint8_t* pBuffer, uint32_t len);

/**
 * @desc  : 向norflash写入数据
 * @date  : 2025-04-24
 * @author: AnRui
 * @param : writeAddr - {参数说明}:
 * @param : pBuffer - {参数说明}:
 * @param : len - {参数说明}:
 * @note  :
 */
void WriteNorflashData(uint32_t writeAddr, uint8_t* pBuffer, uint32_t len);


/**
 * @desc  : norflash测试代码
 * @date  : 2025-04-25
 * @author: AnRui
 * @note  :
 */
void NorflashDrvTest(void);



#endif // __NORFLASH_H__
